home *** CD-ROM | disk | FTP | other *** search
- Subject: v16i071: A simple formatter
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: lee@uhccux.uhcc.hawaii.edu (Greg Lee)
- Posting-number: Volume 16, Issue 71
- Archive-name: xfmt
-
- [ This will be the last one of these, unless anyone has an nroff
- emulator, as we're moving past the "simple" stage now.
- Note that it uses FLEX, which appeared here several months
- ago. --r$ ]
-
- Xfmt fills out lines by paragraphs, like the BSD fmt program.
- The first version of xfmt, 'extended fmt', was written by Bill Gray
- (bgray@marque.mu.edu) and appeared in comp.sources.misc as "fmt".
-
- This version interprets a few nroff -man commands or a (very) few
- TeX commands, or both, if you ask it to (by using the -m or -x flags).
- It does a more complete job of interpreting fonts in terms of screen
- attributes than can be done nroff(1) and ul(1). There is also a -c flag
- for displaying C code with comments highlighted and keywords shown with
- various screen attributes.
-
- Many man pages are not correctly processed, since many have nroff
- commands not interpreted by xfmt. The addition of -man interpretation
- and other features to xfmt will not be to everyone's taste, especially
- since they are incompletely implemented.
-
- The BSD termcap facility is used in this version of xfmt. Also, you
- need flex, by Vern Paxson et al. to make xfmt. Unless a second version
- of flex has been distributed by now, you will need to modify flex's
- skeleton files by making the changes described in the REAMDE file.
-
- -- Greg Lee
- U.S.mail: 562 Moore Hall, Dept. of Linguistics, Univ. of Hawaii, HONO, HI 96822
- INTERNET: lee@uhccux.uhcc.hawaii.edu
- UUCP: {ihnp4,dcdwest,ucbvax}!sdcsvax!nosc!uhccux!lee
- BITNET: lee@uhccux
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: MANIFEST Makefile README cmds.tex flex.skel.diff xfmt.1 xfmt.l
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(402 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X MANIFEST 1
- X Makefile 1
- X README 1
- X cmds.tex 1 list of formatting commands
- X flex.skel.diff 1 patch for flex distribution file
- X xfmt.1 1 man page
- X xfmt.l 1 (f)lex source for xfmt
- END_OF_FILE
- if test 402 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(791 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X# file: xfmt/Makefile
- X# 04/88 bgray, rev. 05/88 by Greg Lee
- X
- X
- BINDIR = /usr/lbin
- MANDIR = /usr/man/u_man/man1
- CATMAN = /usr/catman/u_man/man1
- X
- LIBS = -ltermcap
- CFLAGS = -O
- LDFLAGS = -s
- CC = /bin/cc
- RM = /bin/rm -f
- CP = /bin/cp
- X
- OBJS =
- X
- X
- all: xfmt
- X
- xfmt: xfmt.c
- X $(CC) $(CFLAGS) $(LDFLAGS) -o xfmt xfmt.c $(LIBS)
- X
- xfmt.c: xfmt.l
- X @rm -f xfmt.c
- X flex -t xfmt.l >xfmt.c
- X
- xfmt.doc: xfmt.1 xfmt
- X xfmt -jmo xfmt.1 >xfmt.doc
- X
- shar: xfmt.l xfmt.1 README Makefile MANIFEST cmds.tex flex.skel.diff
- X @rm -f xfmt.shar
- X makekit -m -nxfmt.shar.
- X
- install: all xfmt.doc
- X $(CP) xfmt $(BINDIR)
- X chown bin $(BINDIR)/xfmt
- X chgrp bin $(BINDIR)/xfmt
- X chmod 755 $(BINDIR)/xfmt
- X $(CP) xfmt.doc $(CATMAN)/xfmt.1
- X chown bin $(CATMAN)/xfmt.1
- X chgrp bin $(CATMAN)/xfmt.1
- X chmod 644 $(CATMAN)/xfmt.1
- X
- clean:
- X rm xfmt.c
- END_OF_FILE
- if test 791 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(2168 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X
- The first version of xfmt, 'extended fmt', was written by Bill Gray
- X(bgray@marque.mu.edu) and appeared in comp.sources.misc as "fmt".
- Since it is nearly downward compatible with the BSD fmt program
- X(treatment of ending sentence punctuation is a little different), you
- might choose to name your version "xfmt" -- or not.
- X
- This version interprets a few nroff -man commands or a (very) few
- TeX commands, or both, if you ask it to (by using the -m or -x flags).
- It does a more complete job of interpreting fonts in terms of screen
- attributes than can be done nroff(1) and ul(1). There is also a -c flag
- for displaying C code with comments highlighted and keywords shown with
- various screen attributes.
- X
- Many man pages are not correctly processed, since many have nroff
- commands not interpreted by xfmt. The addition of -man interpretation
- and other features to xfmt will not be to everyone's taste, especially
- since they are incompletely implemented.
- X
- The BSD termcap facility is used in this version of xfmt. Also, you
- need flex, by Vern Paxson et al. to make xfmt. Unless a second version
- of flex has been distributed by now, you will need to modify flex's
- skeleton files by making the following changes:
- X
- CHANGE
- static int yy_start; /* start state number */
- TO
- static int yy_start = 0; /* start state number */
- X
- CHANGE
- X yy_start = 1; /* first start state */
- TO
- X if (!yy_start) yy_start = 1; /* first start state */
- X
- Or you can try "patch < flex.skel.diff" to make the changes
- automatically in the distributed version of the file flex.skel. (This
- patch file includes another patch concerning the reject action.) The
- change to flex is required so xfmt can choose a start condition in its
- main() procedure depending on what flags it sees on the command line.
- X
- Once you have made xfmt, the accompanying documents can be displayed
- with:
- X xfmt -mu xfmt.1
- X xfmt -xu cmds.tex
- X xfmt -c xfmt.l
- X
- X
- The amount of pattern matching done in this version of xfmt exceeds the
- capacity of lex by quite a bit. This kind of program is now easy to do
- thanks to the implementors of flex: Vern Paxson, Kevin Gong, Jef
- Poskanzer, Van Jacobson.
- X
- X Greg Lee, lee@uhccux.uhcc.hawaii.edu
- END_OF_FILE
- if test 2168 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'cmds.tex' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cmds.tex'\"
- else
- echo shar: Extracting \"'cmds.tex'\" \(5328 characters\)
- sed "s/^X//" >'cmds.tex' <<'END_OF_FILE'
- X
- X{\it xfmt} formatting commands.}
- X\bigskip
- X
- X\centerline{\it Nroff/man~commands with \tt xfmt~-mu}
- X\medskip
- X
- X\item{\tt .sp~(n)} Skip 1 (or n) lines.
- X\item{\tt \\fI} Start {\it underlining} of text (termcap "ul").
- X\item{\tt \\fB} Start {\bf bold} text (termcap "md").
- X\item{\tt \\fS} Start {\tt reversed} text (termcap "mr").
- X\item{\tt \\fG} Start {\sl blinking} text (termcap "mb").
- X\item{\tt \\fR} End {\it underlining} or other special text
- X (termcap "me"/"ue").
- X\item{\tt \\fP} Same as {\tt \\fR} (bug).
- X\item{\tt .nf} Stop filling lines to maximum width.
- X\item{\tt .fi} Resume filling lines to maximum width.
- X\item{\tt .I~<line>} Display <line> {\it underlined}.
- X\item{\tt .B~<line>} Display <line> in {\bf bold}.
- X\item{\tt .S~<line>} Display <line> {\tt reversed}.
- X\item{\tt .G~<line>} Display <line> {\sl blinking}.
- X\item{\tt .SM~<line>} Display <line> {\tt reversed}.
- X\item{\tt .R~<line>} Display <line> plain.
- X\item{\tt .CT~<char>} Display <char> reversed or "<CTRL/<char>>"
- X in case neither -u or -o was given.
- X\item{\tt \\*(lq} Display "`".
- X\item{\tt \\*(rq} Display "'".
- X\item{\tt \\(*<char>} Display <char> reversed.
- X\item{\tt \\(<char><char>}
- X Display <char><char> reversed.
- X\item{\tt \\s(-)<digit>}
- X Ignored.
- X\item{\tt \\| \\\^ \\\& \\! \\\{ \\\} \\a \\c \\d \\e \\p \\r \\t \\u \\z}
- X Ignored.
- X\item{\tt \\} Display following character (except as above).
- X\item{\tt .br} Terminate preceding paragraph.
- X\item{\tt .PP} Terminate preceding paragraph.
- X\item{\tt .P} Terminate preceding paragraph.
- X\item{\tt .LP} Terminate preceding paragraph.
- X\item{\tt .TP~(n)} Begin hanging paragraph with 5 (or n) extra
- X spaces of indentation at left, with first
- X following line in left margin.
- X\item{\tt .IP~<word>~(0.3i)~...}
- X Begin hanging paragraph with 5 extra
- X spaces of indentation at left, with <word> ...
- X in left margin.
- X\item{\tt .HP~(n)} Begin hanging paragraph with 5 extra
- X spaces of indentation at left.
- X\item{\tt .RS} Indent 5 extra spaces until {\tt .RE}.
- X\item{\tt .RE} Resume normal indent after {\tt .RS}.
- X\item{\tt .DS} Skip a line; preserve lines and spacing;
- X indent 5 extra spaces until {\tt .DE}.
- X\item{\tt .DE} Resume filling and normal indent after {\tt .DS}.
- X\item{\tt .EX} Skip a line; preserve lines and spacing;
- X indent 5 extra spaces until {\tt .EE}.
- X\item{\tt .EE} Skip a line; resume filling and normal indent
- X after {\tt .EX}.
- X\item{\tt .VS~<line>} Ignored.
- X\item{\tt .VE~<line>} Ignored.
- X\item{\tt .NT~(<line>)} Skip a line, indent 5 extra spaces, shorten
- X line length by 5, display {\bf NOTE} bold and
- X centered (or <line>), continue until {\tt .NE}.
- X\item{\tt .NE} Resume normal indent and line length after
- X {\tt .NT}.
- X\item{\tt .IR~<words>} Join words alternating {\it underlined} and plain.
- X\item{\tt .BR~<words>} Join words alternating {\bf bold} and plain.
- X\item{\tt .RI~<words>} Join words alternating plain and {\it underlined}.
- X\item{\tt .BI~<words>} Join words alternating {\bf bold} and {\it underlined}.
- X\item{\tt .RB~<words>} Join words alternating plain and {\bf bold}.
- X\item{\tt .IB~<words>} Join words alternating {\it underlined} and {\bf bold}.
- X\item{\tt .SH~<line>} Skip a line, and display <line> left adjusted
- X and {\bf bold}.
- X\item{\tt .SS~<line>} Skip a line, and display <line> {\bf bold}.
- X\item{\tt .TH~<name>~<n>~(<text>)}
- X Right adjust {\bf <name>(<n>)} (followed by <text>).
- X\item{\tt .UC~(<digit>)}
- X Ignored.
- X\item{\tt .\\"~<line>} Ignore <line>.
- X\item{\tt .PN~<line>} Underline <line>.
- X\item{\tt .ta~<line>} Ignore <line>.
- X\item{\tt .PD~<line>} Ignore <line>.
- X\item{\tt .NX<cap>~<line>}
- X Ignore <line>.
- X\item{\tt .DT} Ignored.
- X\item{\tt .ti~+n~<line>}
- X n extra spaces of indentation at left of <line>.
- X\item{\tt .MS~<word>~<n>}
- X Display {\it <word>(<n>)}.
- X
- X
- X\bigskip
- X\centerline{\it \TeX ~commands with \tt xfmt~-xu}
- X\medskip
- X
- X\item{\tt \\vskip} Skip a line.
- X\item{\tt \\bigskip} Skip a line.
- X\item{\tt \\medskip} Skip a line.
- X\item{\tt \\smallskip} Skip a line.
- X\item{\tt \\\$ \\\# \\\{ \\\} \\\& \\\% \\^ \\_ \\\~ \\' \\" \\\\}
- X Display character following \\.
- X\item{\tt\\backslash} Display \backslash.
- X\item{\tt \\it} Begin {\it underlining} (termcap "ul").
- X\item{\tt \\sl} Begin {\sl blinking} (termcap "mb").
- X\item{\tt \\bf} Begin {\bf bold} (termcap "md").
- X\item{\tt \\rm} Begin plain.
- X\item{\tt \\tt} Begin {\tt reverse} (termcap "mr").
- X\item{\tt \\TeX} Display \TeX.
- X\item{\tt \\centerline~<line>}
- X Display <line> centered.
- X\item{\tt\\beginsection~<line>}
- X Skip a line, display <line> in bold.
- X\item{\tt \\rightline~<line>}
- X Display <line> right adjusted.
- X\item{\tt \\raggedright}
- X Stop justifying (for current \{...\} group).
- X\item{\tt \\obeylines} Stop filling lines and preserve spacing
- X (for current \{...\} group).
- X\item{\tt \\obeyspaces} Stop filling lines and preserve spacing
- X (for current \{...\} group).
- X\item{\tt \\item\{...\}}
- X Start hanging paragraph with 10 extra
- X spaces of left indentation and ... displayed in
- X left margin and indented 5.
- X\item{\tt \\itemitem\{...\}}
- X Same as {\tt \\item}.
- X\item{\tt \\<space-character>}
- X Break between words.
- X\item{\tt \~} Space that does not break between words and
- X is displayed with current display attribute.
- X\item{\tt \$} Ignored.
- X\item{\tt \#} Ignored.
- X
- X\bigskip
- X\rightline{Greg Lee, May, 1988}
- X\bye
- END_OF_FILE
- if test 5328 -ne `wc -c <'cmds.tex'`; then
- echo shar: \"'cmds.tex'\" unpacked with wrong size!
- fi
- # end of 'cmds.tex'
- fi
- if test -f 'flex.skel.diff' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'flex.skel.diff'\"
- else
- echo shar: Extracting \"'flex.skel.diff'\" \(1605 characters\)
- sed "s/^X//" >'flex.skel.diff' <<'END_OF_FILE'
- X*** flex.skel.orig Tue May 31 16:32:11 1988
- X--- flex.skel Tue May 31 16:35:25 1988
- X***************
- X*** 12,18
- X /* these variables are all declared out here so that section 3 code can
- X * manipulate them
- X */
- X! static int yy_start, yy_b_buf_p, yy_c_buf_p, yy_e_buf_p;
- X static int yy_saw_eof, yy_init = 1;
- X
- X /* yy_ch_buf has to be 1 character longer than YY_BUF_SIZE, since when
- X
- X--- 12,18 -----
- X /* these variables are all declared out here so that section 3 code can
- X * manipulate them
- X */
- X! static int yy_start = 0, yy_b_buf_p, yy_c_buf_p, yy_e_buf_p;
- X static int yy_saw_eof, yy_init = 1;
- X
- X /* yy_ch_buf has to be 1 character longer than YY_BUF_SIZE, since when
- X***************
- X*** 28,33
- X YY_DECL
- X {
- X int yy_n_chars, yy_lp, yy_iii, yy_buf_pos, yy_act;
- X
- X %% user's declarations go here
- X
- X
- X--- 28,36 -----
- X YY_DECL
- X {
- X int yy_n_chars, yy_lp, yy_iii, yy_buf_pos, yy_act;
- X+ #ifdef FLEX_REJECT_ENABLED
- X+ int yy_full_match;
- X+ #endif
- X
- X %% user's declarations go here
- X
- X***************
- X*** 34,40
- X if ( yy_init )
- X {
- X YY_INIT;
- X! yy_start = 1;
- X yy_init = 0;
- X }
- X
- X
- X--- 37,43 -----
- X if ( yy_init )
- X {
- X YY_INIT;
- X! if (!yy_start) yy_start = 1;
- X yy_init = 0;
- X }
- X
- X***************
- X*** 41,46
- X goto get_next_token;
- X
- X do_action:
- X for ( ; ; )
- X {
- X YY_DO_BEFORE_ACTION
- X
- X--- 44,55 -----
- X goto get_next_token;
- X
- X do_action:
- X+
- X+ #ifdef FLEX_REJECT_ENABLED
- X+ /* remember matched text in case we back up due to trailing context */
- X+ yy_full_match = yy_c_buf_p;
- X+ #endif
- X+
- X for ( ; ; )
- X {
- X YY_DO_BEFORE_ACTION
- END_OF_FILE
- if test 1605 -ne `wc -c <'flex.skel.diff'`; then
- echo shar: \"'flex.skel.diff'\" unpacked with wrong size!
- fi
- # end of 'flex.skel.diff'
- fi
- if test -f 'xfmt.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xfmt.1'\"
- else
- echo shar: Extracting \"'xfmt.1'\" \(4161 characters\)
- sed "s/^X//" >'xfmt.1' <<'END_OF_FILE'
- X.TH XFMT 1 LOCAL
- X.SH NAME
- xfmt \- a simple text formatter
- X.SH SYNOPSIS
- X.B xfmt
- X[
- X.B \-i
- X] [
- X.B \-j
- X] [
- X.B \-m
- X] [
- X.B \-x
- X] [
- X.B \-o
- X] [
- X.B \-u
- X] [
- X.B \-c
- X] [
- X.B \-l n
- X] [
- X.B \-p n
- X] [
- X.B \-t n
- X] [ filenames ]
- X.SH DESCRIPTION
- X.I Xfmt
- is a simple text formatter. With no options present, the default
- behavior of
- X.I xfmt
- is to copy its input (from specified files or from stdin, if no files
- are specified) to its output but with input reformatted into lines no
- longer than 72 characters long. A blank line is taken to indicate the
- beginning of a new paragraph. Lines that begin with a period are
- preserved.
- X.PP
- The following options modify this behavior:
- X.TP
- X.B \-i
- This option will cause
- X.I xfmt
- to preserve indentations. Blanks or tabs at the beginning of a line
- will be considered the beginning of a new paragraph.
- X.TP
- X.B \-j
- Justify output lines. (The default behavior of
- X.I xfmt
- is to output lines with a ragged right margin).
- X.TP
- X.B \-m
- Interpret a few commonly used
- X.I nroff
- X-man commands.
- Those understood (in some fashion) are:
- X.DS
- X .B .I .R .S .G .SM .C
- X .IR .BR .RI .BI .RB .IB
- X .SH .SS .TH .PP .P .LP .TP .IP .HP
- X .RS .RE .DS .DE .NT .NE .VS .VE
- X .CT .PN .MS
- X .UC (ignored) .DT (ignored) .PD (ignored)
- X.DE
- X.sp
- And a few other nroff commands that occur commonly in man
- pages are recognized:
- X.DS
- X \\fI \\fB \\fR \\fP \\fC
- X .sp .br .nf .fi .ti
- X .\\" \\*(lq \\*(rq .ta (ignored)
- X.DE
- X.sp
- More details can be found in the document
- X.IR cmds.tex .
- X.TP
- X.B \-x
- Interpret a few commonly used
- X.I TeX
- commands.
- Those understood (in some fashion) are:
- X.DS
- X \\vskip \\bigskip \\medskip \\smallskip \\$ \\# \\{ \\}
- X \\& \\% \\^ \\_ \\~ \\' \\" \\\\ \\it \\sl \\bf \\rm \\tt
- X \\TeX \\centerline \\rightline \\raggedright \\obeylines \\item
- X { } \\(space) ~ $ (ignored) \\backslash \\beginsection
- X.DE
- X.TP
- X.B \-o
- Produce bold and underlined text with overstriking.
- If the terminal and termcap entries permit, the bold and underlined
- portions can be seen on the screen by feeding
- X.I xfmt
- output to
- X.MS ul 1 .
- Bold is produced by fonts B/bf, S/tt, and underlined
- by I/it, G/sl.
- X.TP
- X.B \-u
- Produce bold, underlined, reversed, and blinking text for terminal
- display (using termcap md, us, mr, and mb entries, respectively).
- This is useful only if one of the options -m or -x is also chosen.
- Bold is produced by font B/bf, underlined by I/it, reversed by S/tt,
- and blinking by G/sl.
- X.TP
- X.B \-c
- XFor C code, display comments reversed, flow-of-control keywords
- in bold, storage-class keywords underlined, and pre-processor
- keywords blinking.
- No formatting is done. The -u option is assumed unless the -o
- option is given.
- X.TP
- X.B \-l n
- This option can be used to change the line length from the default of 72
- characters.
- X.TP
- X.B \-p n
- Change the page offset. This option will cause the output lines to be
- offset the indicated number of columns from the left.
- X.TP
- X.B \-t n
- Set tab size. This option is useful only with the
- X.B \-i
- or
- X.B \-c
- options, or for text in the scope of .nf, .EX, .DS, \obeylines or \obeyspaces,
- since otherwise tabs are treated the same as space characters.
- X.SH EXAMPLES
- Display a man page
- X.I binmail.1
- on the screen with right justification, a page at a time:
- X.EX
- xfmt -jmu binmail.1 | more -f
- X.EE
- Display a man page with underlining, but no bold face:
- X.EX
- xfmt -mo binmail.1 | more -f
- X.EE
- Prepare a preformatted man page to be displayed with
- X.MS ul 1 :
- X.EX
- xfmt -mo binmail.1 >binmail.doc
- X.EE
- Display high-lighted C source code on the screen:
- X.EX
- xfmt -c \fIfile\fR.c
- X.EE
- X.SH TIPS
- In
- X.IR vi ,
- you can define a macro that will reformat paragraphs by typing
- X.I ":map V {!}xfmt^M"
- or by putting the line
- X.RS
- X.I "map V {!}xfmt^M"
- X.RE
- in your
- X.I .exrc
- file. After defining this macro, pressing
- X.I V
- will cause the paragraph under the cursor to be reformatted. (Use the
- X.I u
- key to
- X.I undo
- if necessary.
- X.SH "SEE ALSO"
- nroff(1), vi(1), ul(1)
- X.SH BUGS
- TeX command interpretation doesn't have a chance of working except
- for files prepared with the limitations of xfmt in mind.
- Nroff -man interpretation has maybe a 50-50 chance.
- X.SH AUTHORS
- original version: bgray@marque.mu.edu (Bill Gray)
- X.br
- TeX, man, C mods: lee@uhccux.uhcc.hawaii.edu (Greg Lee)
- END_OF_FILE
- if test 4161 -ne `wc -c <'xfmt.1'`; then
- echo shar: \"'xfmt.1'\" unpacked with wrong size!
- fi
- # end of 'xfmt.1'
- fi
- if test -f 'xfmt.l' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xfmt.l'\"
- else
- echo shar: Extracting \"'xfmt.l'\" \(21023 characters\)
- sed "s/^X//" >'xfmt.l' <<'END_OF_FILE'
- X%{
- X
- X/*
- X * (was file: fmt.c)
- X * 04/88 bgray
- X * file: xfmt.l
- X * revised with (f)lex front end
- X * 05/88 Greg Lee
- X */
- X
- X/* a simple text formatter */
- X
- X#ifndef lint
- static char xfmt_sccsid[] = "@(#)xfmt.l <05/30/88>";
- X#endif lint
- X
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <string.h>
- X
- X#ifndef TRUE
- X#define TRUE 1
- X#endif
- X#ifndef FALSE
- X#define FALSE 0
- X#endif
- X
- X/* character attributes controlled by font-changing commands */
- X#define ROMAN 1 /* plain, from \rm or .R */
- X#define ITALIC 2 /* underlined, from \it or .I */
- X#define BOLD 3 /* bold, from \bf or .B */
- X#define TTYPE 4 /* reversed, from \tt or .S */
- X#define SLANTY 5 /* blinking, from \sl or .G */
- X
- int attribute = ROMAN, /* current character attribute */
- X nextattribute = 0; /* attribute to restore after next
- X * word for .RB, etc. or after line
- X * for \beginsection
- X */
- char nest[80]; /* stack of attributes for each current */
- int level = 1; /* TeX {}-group */
- X
- X/* global state of formatter */
- char iflag = FALSE, /* preserving left indentation (-i)? */
- X jflag = FALSE, /* requested justification with -j? */
- X oflag = FALSE, /* requested overprint with -o? */
- X uflag = FALSE, /* requested terminal output with -u? */
- X xflag = FALSE, /* requested use TeX commands w. -x? */
- X mflag = FALSE, /* requested use man commands w. -m? */
- X cflag = FALSE, /* requested format C code w. -c? */
- X qtflag = FALSE, /* saw odd " in processing .RB etc.? */
- X ceflag = FALSE, /* center next output line? */
- X raflag = FALSE, /* right adjust next output line? */
- X obflag = FALSE, /* not concatenating? */
- X njflag = FALSE; /* not currently justifying? */
- X
- int maxlen = 72,
- X tabsize = 8,
- X indent = 0,
- X offset = 0,
- X tpstate = 0, /* keep track for hanging indentation */
- X tpvalue = 5, /* amount of hang, from arg of .TP,.HP */
- X spaces = 0, /* space to leave after current word */
- X tempi; /* misc. use in lex pattern section */
- X
- char *progname = NULL;
- char *usage = "usage: %s [-ijcmxou] [-l n] [-p n] [-t n] [file ...]\n";
- X
- int dir = FALSE;
- int holecnt = 0;
- char *holeptr[256]; /* holeptr[0] is unused */
- X
- char oline[2048] = "\0", /* output line buffer */
- X *olp = oline,
- X aline[2048] = "\0", /* output line attribute buffer */
- X *alp = aline,
- X oword[512] = "\0", /* output word buffer */
- X *owp = oword,
- X aword[512] = "\0", /* output word attribute buffer */
- X *awp = aword;
- X
- extern char *optarg; /* from getopt */
- extern int optind;
- X
- int max ();
- void exit ();
- char *basename ();
- void copyindent ();
- void puttc ();
- void putts ();
- void lbreak ();
- void putword ();
- void justifyline ();
- void putline ();
- void sputline ();
- void skipline ();
- void addparens ();
- void terminit ();
- void termattr ();
- X
- X%}
- X
- X/* lex start state for flags: -x, -m, (none), -mx, respectively */
- X%s TEX MAN PLAIN ALL CCODE
- X
- X/* match end of TeX command */
- wh [ \t]*/[^a-z]
- X
- X%%
- X
- X<MAN,ALL>^".sp" skipline(1);
- X
- X/* match various TeX skip commands */
- X<TEX,ALL>\\[a-gi-z]+"skip"{wh} skipline(1);
- X
- X/* blank line in input gives blank line in output -- not like real TeX */
- X\n$ skipline(1);
- X
- X<MAN,ALL>^".sp "[0-9]+ skipline(atoi(yytext+4));
- X
- X/* traditional */
- X<PLAIN>^\..* {
- X lbreak();
- X (void)printf("%s\n",yytext);
- X}
- X
- X/* escaped special characters -- \\ for \ not like real TeX */
- X<TEX,ALL>\\[$#{}&%^_~'"\\] puttc(yytext[1]);
- X
- X/* some font-changing commands */
- X
- X<TEX,ALL>"\\it"{wh} |
- X<MAN,ALL>"\\f"("I"|"C") attribute = ITALIC;
- X
- X<TEX,ALL>"\\sl"{wh} |
- X<MAN,ALL>"\\fG" attribute = SLANTY;
- X
- X<TEX,ALL>"\\bf"{wh} |
- X<MAN,ALL>"\\fB" attribute = BOLD;
- X
- X<TEX,ALL>"\\rm"{wh} |
- X<MAN,ALL>"\\f"("R"|"P") attribute = ROMAN; /* \fP should not be like \fR */
- X
- X<TEX,ALL>"\\tt"{wh} |
- X<MAN,ALL>"\\fS" attribute = TTYPE;
- X
- X
- X<TEX,ALL>"\\TeX"{wh} putts("TeX");
- X
- X/* should these 4 TeX commands cause breaks? */
- X<TEX,ALL>\\"centerline"{wh} ceflag = TRUE;
- X
- X<TEX,ALL>\\"rightline"{wh} raflag = TRUE;
- X
- X<TEX,ALL>\\"raggedright"{wh} njflag = level;
- X
- X<TEX,ALL>\\"obeylines"{wh} obflag = level;
- X
- X<MAN,ALL>^".nf" lbreak(); obflag = TRUE;
- X
- X<MAN,ALL>^".fi" lbreak(); obflag = FALSE;
- X
- X<TEX,ALL>"{" nest[level++] = attribute; /* push attr. onto stack */
- X
- X<TEX,ALL>"}" { /* if emerging from {} in which \obeylines or
- X * \raggedright occurred, cancel (not a very general
- X * strategy)
- X */
- X if (obflag == level) obflag = FALSE;
- X if (njflag == level) njflag = FALSE;
- X /* pop attribute off stack */
- X if (level > 1) attribute = nest[--level];
- X /* } after \item signals end of tag; will not
- X * work right with {} inside tag */
- X if (tpstate == 1) {
- X tpstate = 2;
- X putword();
- X }
- X}
- X
- X
- X^[ \t]+ {
- X putword();
- X if (iflag || obflag) {
- X putline();
- X tempi = attribute;
- X /* for comments with indentation */
- X if (cflag) attribute = ROMAN;
- X copyindent(yytext);
- X attribute = tempi;
- X }
- X else if (mflag)
- X putline();
- X}
- X
- X<TEX,ALL>"\\ " putword();
- X
- X<MAN,ALL,CCODE>\n { /* for C code reverse all of multiline comments */
- X if (!cflag) attribute = ROMAN;
- X nextattribute = qtflag = FALSE;
- X /* signal end of tag for hanging indent */
- X if (tpstate == 1) tpstate = 2;
- X putword();
- X if (obflag) putline();
- X}
- X
- X/* more font-changing */
- X
- X<MAN,ALL>^\.B" " attribute = BOLD;
- X
- X<MAN,ALL>^\.(I|C)" " attribute = ITALIC;
- X
- X<MAN,ALL>^\.R" " attribute = ROMAN;
- X
- X<MAN,ALL>^\.("S"|"SM")" " attribute = TTYPE;
- X
- X<MAN,ALL>^\.G" " attribute = SLANTY;
- X
- X<MAN,ALL>\\[\|\^&!{}\nacdeprtuz] ;
- X
- X<MAN,ALL>\\. puttc(yytext[1]);
- X
- X<MAN,ALL>^".ti +"[0-9]+ {
- X lbreak();
- X for (tempi = 0; tempi < atoi(yytext+5) - 1; tempi++)
- X puttc(' ');
- X}
- X
- X<MAN,ALL>^\.br lbreak();
- X
- X<MAN,ALL>^\.(P|L|"")P skipline(1); indent = 5;
- X
- X/* hanging indent stuff (awfully complicated) */
- X
- X<MAN,ALL>^\.(T|H)"P "[0-9]+\n {
- X skipline(1);
- X if (yytext[1] == 'H')
- X tpstate = 4;
- X else tpstate = 1;
- X tpvalue = atoi(yytext+4);
- X indent = 5;
- X}
- X
- X<TEX,ALL>\\"item"("item")?{wh} |
- X<MAN,ALL>^".HP ".*\n |
- X<MAN,ALL>^".TP".*\n |
- X<MAN,ALL>^".IP"[ \t]*\n? {
- X skipline(1);
- X if (yytext[1] == 'I' && yytext[3] == '\n')
- X tpstate = 4;
- X else tpstate = 1;
- X tpvalue = 5;
- X indent = 5;
- X}
- X
- X/* various begin-end commands to set off blocks of text */
- X
- X<MAN,ALL>^"."(R|D)(S|E) {
- X if (yytext[1] == 'D' && yytext[2] == 'S') {
- X skipline(1);
- X obflag = TRUE;
- X }
- X else lbreak();
- X indent = 10;
- X if (yytext[2] == 'E') {
- X indent = 5;
- X obflag = FALSE;
- X }
- X}
- X
- X<MAN,ALL>^".E"(X|E) {
- X skipline(1);
- X if (yytext[2] == 'E') {
- X indent = 5;
- X obflag = FALSE;
- X }
- X else { indent = 10;
- X obflag = TRUE;
- X }
- X}
- X
- X
- X<MAN,ALL>^".N"(T|E).* {
- X skipline(1);
- X if (yytext[2] == 'E') {
- X indent = 5;
- X maxlen += 5;
- X }
- X else { indent = 10;
- X maxlen -= 5;
- X tempi = attribute;
- X attribute = ITALIC;
- X ceflag = TRUE;
- X if (yyleng < 5) putts("NOTE");
- X else putts(yytext+4);
- X skipline(1);
- X }
- X}
- X
- X/* those curious -man commands to join words, alternating fonts */
- X
- X<MAN,ALL>^\.("IR"|"PN")" " nextattribute = ROMAN; attribute = ITALIC;
- X
- X<MAN,ALL>^\."BR " nextattribute = ROMAN; attribute = BOLD;
- X
- X<MAN,ALL>^\."RI " nextattribute = ITALIC; attribute = ROMAN;
- X
- X<MAN,ALL>^\."BI " nextattribute = ITALIC; attribute = BOLD;
- X
- X<MAN,ALL>^\."RB " nextattribute = BOLD; attribute = ROMAN;
- X
- X<MAN,ALL>^\."IB " nextattribute = BOLD; attribute = ITALIC;
- X
- X/* section headings */
- X
- X<TEX,ALL>\\"beginsection"{wh} {
- X skipline(1);
- X nextattribute = attribute;
- X attribute = BOLD;
- X}
- X
- X<MAN,ALL>^\."S"(H|S)" ".* {
- X skipline(1);
- X if (yytext[2] == 'H')
- X indent = 0;
- X attribute = BOLD;
- X putts(yytext+4);
- X lbreak();
- X indent = 5;
- X attribute = ROMAN;
- X}
- X
- X<MAN,ALL>^\."TH ".* {
- X lbreak();
- X indent = 0;
- X addparens(yytext+4, BOLD);
- X raflag = TRUE;
- X skipline(2);
- X indent = 5;
- X}
- X
- X/* "Manual Section" reference */
- X<MAN,ALL>^".MS ".* addparens(yytext+4, ITALIC);
- X
- X<MAN,ALL>^".CT ". {
- X if (uflag || oflag) {
- X tempi = attribute;
- X attribute = TTYPE;
- X puttc(toupper(yytext[4]));
- X attribute = tempi;
- X }
- X else {
- X putts("<CTRL/");
- X puttc(yytext[4]);
- X puttc('>');
- X }
- X}
- X
- X<MAN,ALL>^".V"(S|E).* |
- X<MAN,ALL>^".UC"(..)? |
- X<MAN,ALL>^\.\\\".* ;
- X
- X/* for join-words commands, words can be quoted */
- X<MAN,ALL>\" {
- X if (nextattribute || tpstate == 1) {
- X qtflag = !qtflag;
- X }
- X else puttc('"');
- X}
- X
- X<MAN,ALL,CCODE>" " {
- X if (nextattribute) {
- X if (qtflag) puttc(' ');
- X else {
- X tempi = attribute;
- X attribute = nextattribute;
- X nextattribute = tempi;
- X }
- X }
- X else {
- X putword();
- X if (obflag) copyindent(yytext);
- X }
- X}
- X
- X<TEX,ALL,CCODE>\n {
- X putword();
- X if (obflag || nextattribute) putline();
- X if (nextattribute) {
- X attribute = nextattribute;
- X nextattribute = 0;
- X }
- X}
- X
- X<TEX,ALL>"~" puttc(' ');
- X
- X[ \t]+ {
- X putword();
- X if (obflag) copyindent(yytext);
- X}
- X
- X[\n\r\f] putword();
- X
- X<TEX,ALL>\\"backslash"{wh} puttc('\\');
- X
- X<TEX>\\ |
- X<TEX,ALL>\$|\# ;
- X
- X<TEX,ALL>\\[A-Za-z]+{wh} ;
- X
- X<MAN,ALL>\\"*(rq" puttc('\'');
- X
- X<MAN,ALL>\\"*(lq" puttc('`');
- X
- X<MAN,ALL>\\"(".. {
- X tempi = attribute;
- X attribute = TTYPE;
- X if (yytext[2] != '*') puttc(yytext[2]);
- X puttc(yytext[3]);
- X attribute = tempi;
- X}
- X
- X<MAN,ALL>\\"s"("-")?[0-9] |
- X<MAN,ALL>"\\*S" |
- X<MAN,ALL>^".DT" |
- X<MAN,ALL>^".ta ".* |
- X<MAN,ALL>^".PD".* |
- X<MAN,ALL>^".NX".* ;
- X
- X<CCODE>\" { if (attribute != TTYPE) qtflag = !qtflag;
- X puttc('"');
- X}
- X
- X<CCODE>"/*" { puttc('/');
- X if (!qtflag) attribute = TTYPE;
- X puttc('*');
- X}
- X
- X<CCODE>"*/" { puttc('*');
- X if (!qtflag) attribute = ROMAN;
- X puttc('/');
- X}
- X
- X/* control flow keywords are bold */
- X<CCODE>"continue"|"default"|"do"|"goto"|"return" |
- X<CCODE>"if"|"else"|"while"|"break"|"switch"|"case"|"for" {
- X if (attribute != TTYPE && !qtflag) {
- X attribute = BOLD;
- X putts(yytext);
- X attribute = ROMAN;
- X } else putts(yytext);
- X}
- X
- X/* storage class keywords are underlined */
- X<CCODE>("auto"|"char"|"double"|"enum"|"extern"|"float") |
- X<CCODE>("int"|"long"|"register"|"short"|"sizeof"|"static") |
- X<CCODE>("struct"|"typedef"|"union"|"unsigned"|"void") {
- X
- X if (attribute != TTYPE && !qtflag) {
- X attribute = ITALIC;
- X putts(yytext);
- X attribute = ROMAN;
- X } else putts(yytext);
- X}
- X
- X/* preprocessor keywords are blinking */
- X<CCODE>"#"[ \t]*("define"|"undef"|"include"|"if"|"ifdef") |
- X<CCODE>"#"[ \t]*("ifndef"|"else"|"endif"|"line") {
- X
- X if (attribute != TTYPE && !qtflag) {
- X attribute = SLANTY;
- X putts(yytext);
- X attribute = ROMAN;
- X } else putts(yytext);
- X}
- X
- X/* identifiers that happen to contain keywords are plain */
- X<CCODE>[a-zA-Z_]+ putts(yytext);
- X
- X. puttc(yytext[0]);
- X
- X
- X
- X%%
- X
- X/*
- X * Characters, along with the currently active "font"= screen
- X * attribute, are collected in a word buffer until we hit a
- X * word break (white space), then moved to a line buffer.
- X * Words are collected in the line buffer until we hit a line
- X * break (end of paragraph) or the line is long enough, then
- X * the line is output.
- X */
- X
- main (argc, argv)
- int argc;
- char *argv[];
- X{
- X int c, i;
- X
- X progname = basename (argv[0]);
- X while ((c = getopt (argc, argv, "ijcxmoul:p:t:")) != EOF)
- X switch (c) {
- X case 'i': iflag = TRUE; break;
- X case 'j': jflag = TRUE; break;
- X case 'c': cflag = TRUE; break;
- X case 'x': xflag = TRUE; break;
- X case 'm': mflag = TRUE; break;
- X case 'o': oflag = TRUE; break;
- X case 'u': uflag = TRUE; break;
- X case 'l': maxlen = max (0, atoi (optarg));
- X break;
- X case 'p': offset = max (0, atoi (optarg));
- X break;
- X case 't': tabsize = max (1, atoi (optarg));
- X break;
- X default: (void) fprintf (stderr, usage, progname);
- X exit (1);
- X break;
- X }
- X
- X
- X/* set lex start state */
- X if (xflag && mflag) {
- X BEGIN (ALL);
- X }
- X else if (xflag) {
- X BEGIN (TEX);
- X }
- X else if (mflag) {
- X indent = 5;
- X BEGIN (MAN);
- X }
- X else if (cflag) {
- X obflag = TRUE;
- X if (!oflag) uflag = TRUE;
- X BEGIN (CCODE);
- X }
- X else {
- X BEGIN (PLAIN);
- X }
- X
- X/* consult termcap for terminal controls */
- X if (uflag)
- X terminit ();
- X
- X
- X/* call lex scanner */
- X if (optind >= argc) {
- X (void) yylex ();
- X lbreak ();
- X }
- X else
- X for (; (optind < argc); optind++) {
- X if (freopen (argv[optind], "r", yyin) != NULL) {
- X /* unstructured -- couldn't find any other
- X * way to get flex to look at > 1 file */
- X yy_init = 1;
- X (void) yylex ();
- X lbreak ();
- X }
- X else {
- X (void) fprintf (stderr,
- X "Couldn't open file: %s", argv[optind]);
- X exit (1);
- X }
- X }
- X
- X return (0);
- X} /* main */
- X
- X
- X/* preserve spacing due to spaces or tabs */
- void copyindent (ilp)
- char *ilp;
- X{
- X int col;
- X
- X col = (olp - oline) + 1;
- X
- X for (; (isspace (*ilp)); col++) {
- X if (*ilp++ == '\t')
- X for (; (col % tabsize); col++) {
- X *olp++ = ' ';
- X *alp++ = (cflag) ? attribute : ROMAN;
- X }
- X *olp++ = ' ';
- X *alp++ = (cflag) ? attribute : ROMAN;
- X }
- X} /* copyindent */
- X
- X/* one character goes into word buffer */
- void puttc (ch)
- char ch;
- X{
- X *owp++ = ch;
- X *awp++ = attribute;
- X} /* puttc */
- X
- X/* put string in word buffer (might have spaces) */
- void putts (s)
- char *s;
- X{
- X while (*s)
- X puttc (*s++);
- X} /* putts */
- X
- X/* finish pending word and line and put it out (no justification) */
- void lbreak () {
- X putword ();
- X putline ();
- X tpstate = 0;
- X} /* lbreak */
- X
- X/* append pending word to line buffer */
- void putword () {
- X int plen;
- X char *p;
- X char *q;
- X static char started = 0;
- X
- X /* just return if no characters have been accumulated yet */
- X if (owp == oword) {
- X /* this is for the special case in which a file
- X * starts with \n, which should count as a "blank line"
- X */
- X if (!started) {
- X putchar ('\n');
- X started = 1;
- X }
- X return;
- X }
- X started = 1;
- X
- X puttc ('\0');
- X p = oword;
- X q = aword;
- X plen = strlen (p);
- X
- X /* ugly way to ignore "0.3i" arg of .IP */
- X if (tpstate == 2 && *p == '0' && p[plen - 1] == 'i') {
- X spaces = plen = 0;
- X *p = '\0';
- X }
- X
- X /* finish pending line if pending word won't fit */
- X if (!obflag && (olp - oline) + spaces + plen > maxlen - indent) {
- X if ((jflag) && (holecnt) && !njflag)
- X justifyline ();
- X putline ();
- X }
- X
- X /* append spaces which were previously decided to go after
- X * last word put in line buffer */
- X if (spaces) {
- X /* don't use space inside tag of hanging indent to
- X * right justify */
- X if (!tpstate || tpstate > 3)
- X holeptr[++holecnt] = olp;
- X /* if tag already padded out, permit justification
- X * of space after next word */
- X if (tpstate == 3)
- X tpstate = 4;
- X for (; (spaces > 0); spaces--) {
- X *olp++ = ' ';
- X /* a matter of taste -- put just " = ROMAN"
- X * for no underlined spaces between words */
- X *alp++ = (*(alp-1) == ITALIC && *q == ITALIC) ?
- X ITALIC : ROMAN;
- X }
- X }
- X
- X /* figure spaces which should go after pending word which
- X * is just about to be appended in line buffer -- remember
- X * so they can be put before next word (cf. just above) */
- X if (!obflag) spaces = 1 + endofsentence (p, plen);
- X /* (but if spacing is being preserved, as signaled by
- X * obflag, we don't want extra spaces) */
- X
- X /* append pending word in line buffer */
- X while (*p) {
- X *olp++ = *p++;
- X *alp++ = *q++;
- X }
- X
- X /* part of tortuous way of handling hanging indent */
- X /* tpstate = 0: no hanging indent
- X * 1: scanning tag to go in left margin
- X * 2: have seen end of tag, time to
- X * pad out tag to hanging indent value
- X * 3: finished padding
- X * 4: finished first line of hanging par.;
- X * subsequent lines should be indented
- X * to hanging indent value
- X */
- X if (tpstate == 2) { /* time to pad tag? */
- X tpstate = 3; /* signal padding done */
- X if ((olp - oline) + spaces > tpvalue) /* will tag fit? */
- X putline (); /* no it won't, so start new line */
- X else /* yes it will, so pad it out */
- X while ((olp - oline) + spaces < tpvalue)
- X spaces++;
- X }
- X
- X /* purge word buffer -- get ready for next word */
- X owp = oword;
- X awp = aword;
- X} /* putword */
- X
- X
- X/* increase inter-word spacings for right justification */
- void justifyline () {
- X int n;
- X char *fp,
- X *tp,
- X *fa,
- X *ta;
- X
- X dir = (!(dir));
- X fp = olp - 1;
- X fa = alp - 1;
- X olp = &oline[maxlen - indent];
- X alp = &aline[maxlen - indent];
- X tp = olp - 1;
- X ta = alp - 1;
- X while (tp > fp) {
- X while (fp >= holeptr[holecnt]) {
- X *tp-- = *fp--;
- X *ta-- = *fa--;
- X }
- X if (dir)
- X n = ((tp - fp) - 1) / holecnt + 1;
- X else
- X n = (tp - fp) / holecnt;
- X while (n--) {
- X *tp-- = ' ';
- X *ta-- = ta[1];
- X }
- X holecnt--;
- X }
- X} /* justifyline */
- X
- X
- X/* put out pending line in line buffer */
- void putline ()
- X{
- X if (ceflag) {
- X spaces = max ((maxlen - (olp - oline)) / 2, 1) + offset;
- X ceflag = FALSE;
- X }
- X else if (raflag) {
- X spaces = max ((maxlen - (olp - oline)), 1) + offset;
- X raflag = FALSE;
- X }
- X else spaces = indent + offset;
- X
- X *olp = '\0';
- X
- X if (*oline)
- X /* if -u or -x options, have to do it character
- X * by character */
- X if (oflag || uflag)
- X sputline ();
- X else
- X (void) printf ("%*s\n", spaces + strlen (oline), oline);
- X
- X /* purge line buffer -- get ready for new line */
- X *oline = '\0';
- X olp = oline;
- X alp = aline;
- X spaces = 0;
- X holecnt = 0;
- X
- X /* if finished with first line of hanging par., increase
- X * left indent for subsequent lines */
- X if (tpstate > 2) {
- X indent = tpvalue + 5;
- X tpstate = 4;
- X }
- X} /* putline */
- X
- X
- X/* display characters of line with overstriking or with special
- X * terminal attributes */
- void sputline () {
- X char *p;
- X char *q;
- X char last = ROMAN;
- X
- X if (spaces)
- X (void) printf ("%*s", spaces, NULL);
- X
- X for (p = oline, q = aline; *p; p++, q++)
- X if (uflag) {
- X last = newattr (last, *q);
- X (void) printf ("%c", *p);
- X } else
- X switch (*q) {
- X case ROMAN:
- X (void) printf ("%c", *p);
- X break;
- X case BOLD:
- X case TTYPE:
- X if (*p == ' ')
- X printf("%c", *p);
- X else (void) printf ("%c%c%c", *p, 8, *p);
- X break;
- X case ITALIC:
- X case SLANTY:
- X (void) printf ("_%c%c", 8, *p);
- X break;
- X }
- X if (uflag)
- X last = newattr (last, ROMAN);
- X (void) printf ("\n");
- X
- X} /* sputline */
- X
- X/* put blank lines */
- void skipline (n)
- int n;
- X{
- X lbreak ();
- X for (; (n > 0); n--)
- X (void) printf ("\n");
- X if (xflag)
- X indent = 0;
- X} /* skipline */
- X
- X
- X/* decide how many spaces go after word */
- int endofsentence (p, plen)
- char *p;
- int plen;
- X{
- X if (plen < 3)
- X return (FALSE);
- X if (!strchr (".:?!", *(p + plen - 1)))
- X return (FALSE);
- X if (abbr (p))
- X return (FALSE);
- X return (TRUE);
- X} /* endofsentence */
- X
- X
- X/* detect "." which is not real end of sentence */
- int abbr (s)
- char *s;
- X{
- X char *p,
- X *q,
- X *r;
- X
- X while (*s == '(')
- X s++;
- X q = ".i.e.g.dr.mr.mrs.st.";
- X for (; (*q); q++) {
- X p = q;
- X r = s;
- X while ((*r) && (*p++ == (*r++ | 0x20)));
- X if (!*r)
- X return (TRUE);
- X }
- X return (FALSE);
- X} /* abbr */
- X
- X
- X
- char *basename (s)
- char *s;
- X{
- X char *p;
- X
- X if (p = strrchr (s, '/'))
- X return (++p);
- X else
- X return (s);
- X} /* basename */
- X
- X
- X
- int max (a, b)
- int a,
- X b;
- X{
- X return ((a > b) ? a : b);
- X} /* max */
- X
- X
- X/* put parentheses around number of manual section */
- void addparens (s, a)
- char *s;
- int a;
- X{
- X nextattribute = attribute;
- X attribute = a;
- X while (*s && *s != ' ')
- X puttc (*s++);
- X if (*s == ' ')
- X s++, puttc ('(');
- X while (*s && *s != ' ')
- X puttc (*s++);
- X if (*s == ' ')
- X s++;
- X puttc (')');
- X attribute = nextattribute;
- X nextattribute = 0;
- X if (*s && isalpha (*s))
- X puttc (' ');
- X while (*s)
- X puttc (*s++);
- X} /* addparens */
- X
- X/* terminal commands -- accessing routines */
- X
- X/*
- X * following derived from:
- X * tcap v1.0 Enhanced terminal control program
- X * Author: Eric Lorenzo Lim
- X * Modified by: Becca Thomas and Rik Farrow
- X * (appeared in Nov. '87 Unix World)
- X */
- X
- X#define SO 0
- X#define SE 1
- X#define MB 2
- X#define MD 3
- X#define MR 4
- X#define MH 5
- X#define ME 6
- X#define US 7
- X#define UE 8
- char *id[] = {
- X "so", "se", "mb", "md", "mr", "mh", "me", "us", "ue",
- X (char *) NULL,
- X};
- X
- char *area[50];
- char bp[1024],
- X strbuf[1024];
- X
- X/* get for later use terminal handling commands we need */
- void terminit () {
- X int id_size = 0;
- X char *str,
- X *tmpptr;
- X extern char *getenv (), *tgetstr (), *tgoto ();
- X
- X if ((tmpptr = getenv ("TERM")) == (char *) NULL) {
- X (void) fprintf (stderr, "xfmt: TERM variable not set\n");
- X exit (1);
- X }
- X
- X str = strbuf;
- X
- X if (tgetent (bp, tmpptr))
- X while (id[id_size] != (char *) NULL) {
- X area[id_size] = tgetstr (id[id_size], &str);
- X if (area[id_size] == (char *) NULL)
- X area[id_size] = "";
- X id_size++;
- X }
- X
- X
- X} /* terminit */
- X
- X/* put out a terminal handing command */
- void termattr (i)
- int i;
- X{
- X (void) printf ("%s", area[i]);
- X} /* termattr */
- X
- X/* check for change of "font" and send command to terminal
- X * when there is a change */
- int newattr (l, a)
- int l, /* last attribute */
- X a; /* new attribute */
- X{
- X if (l != a) {
- X if (l == BOLD || l == TTYPE || l == SLANTY)
- X termattr (ME);
- X else if (l == ITALIC)
- X termattr (UE);
- X
- X switch (a) {
- X case BOLD: termattr (MD); break;
- X case ITALIC: termattr (US); break;
- X case TTYPE: termattr (MR); break;
- X case SLANTY: termattr (MB); break;
- X }
- X }
- X return (a);
- X} /* newattr */
- X
- END_OF_FILE
- if test 21023 -ne `wc -c <'xfmt.l'`; then
- echo shar: \"'xfmt.l'\" unpacked with wrong size!
- fi
- # end of 'xfmt.l'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
- -- Greg, lee@uhccux.uhcc.hawaii.edu
-
-